package org.simpleframework.mvc;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.simpleframework.mvc.processor.RequestProcessor;
import org.simpleframework.mvc.render.ResultRender;
import org.simpleframework.mvc.render.impl.DefaultResultRender;
import org.simpleframework.mvc.render.impl.InternalErrorResultRender;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Iterator;

/**
 * 1.以责任链的模式执行注册的请求处理器
 * 2.委派给特定的Render实例对处理后的结果进行渲染
 *
 * @author: Oliver
 * @time: 2020/12/28/22:55
 */
@Getter
@Setter
@AllArgsConstructor
@Slf4j
public class RequestProcessorChain {
    /**
     * 处理器链的迭代器
     */
    private Iterator<RequestProcessor> iterator;
    /**
     * http请求
     */
    private HttpServletRequest request;
    /**
     * http响应
     */
    private HttpServletResponse response;
    /**
     * http请求方法
     */
    private String method;
    /**
     * http请求路径
     */
    private String methodPath;
    /**
     * http响应状态码
     */
    private int code;
    /**
     * 请求结果渲染器
     */
    private ResultRender render;

    public RequestProcessorChain(Iterator<RequestProcessor> iterator, HttpServletRequest req, HttpServletResponse resp) {
        this.request = req;
        this.response = resp;
        this.method = req.getMethod();
        this.methodPath = req.getPathInfo();
        this.iterator = iterator;
        // 默认处理器链的状态码为 200
        this.code = HttpServletResponse.SC_OK;
    }

    /**
     * 以责任链的模式进行请求的处理,默认每一个请求都会经过前置处理器,且返回为true,请他处理器只要被处理过就会返回false.
     */
    public void doRequestProcessor() {
        while (iterator.hasNext()) {
            try {
                // 直到某个请求处理器执行后返回为false为止
                if (!iterator.next().process(this)) {
                    break;
                }
            } catch (Exception e) {
                //期间如果抛出异常 ,交由异常渲染器处理,并记录日志
                this.render = new InternalErrorResultRender(e.getMessage());
                log.error("doRequestProcessorChain error:", e);
            }
        }
    }

    /**
     * 执行结果处理器进行渲染结果
     */
    public void doRender() {
        //如果在执行过程中没有适配到任何合适的渲染器,则默认使用DefaultResultRender
        if (render == null) {
            render = new DefaultResultRender();
        }
        // 执行render的 render方法,进行结果处理
        try {
            render.render(this);
        } catch (Exception e) {
            log.error("doRender error:", e);
            throw new RuntimeException();
        }
    }
}
